#include <string.h>
#include <stdlib.h>

// #define WIDTH         16
// #define HEIGHT       8
#define WIDTH           8
#define HEIGHT          14

#define CELL_X        8
#define CELL_Y        1
#define false         0
#define true          1
#define bool          char

typedef enum ELEMENT {
	AIR,
	BLOCK,
	MOVING
}ELEMENT;

typedef enum SHAPE_TYPE {
	O_SHAPE=0, J_SHAPE, L_SHAPE, T_SHAPE, I_SHAPE, S_SHAPE, Z_SHAPE, MAX_SHAPE
}SHAPE_TYPE;

typedef struct COORD {
    char X;
    char Y;
}COORD;

COORD faller[4] = {0};
COORD next_faller[4] = {0};
SHAPE_TYPE now_shape = 0;

//不可修改
char code shapes[MAX_SHAPE][8] = {
	{4,3,5,3,4,4,5,4},
	{4,4,5,4,6,4,4,3},
	{5,4,4,4,3,4,5,3},
	{5,4,4,4,6,4,5,3},
	{4,4,5,4,3,4,6,4},
	{4,3,5,3,4,2,5,4},
	{4,3,5,3,5,2,4,4}
};

char map[HEIGHT][WIDTH]= {0};

typedef enum DIRECTION {
	LEFT,
	RIGHT,
}DIRECTION;

short rand(void) {
    static short seed = 15; // 初始种子值
    seed = (seed * 150 + 1) % 3278; // 生成新的种子值
    seed %= MAX_SHAPE;
    return seed ; // 返回范围在 [0, MAX_SHAPE-1] 的随机数
}

void generate() {
	char i;
    now_shape = (SHAPE_TYPE)(rand() % MAX_SHAPE);
	memcpy(faller, shapes + now_shape, sizeof(faller));
	for (i = 0; i < 4; i++)
	{
		map[faller[i].Y][faller[i].X] = MOVING;
	}
    
}

void printc(u8 x,u8 y,char c){
    OLED_ShowChar(x*CELL_X,y*CELL_Y,c,8);
}

char try_move_down(){
    u8 i;
    for ( i = 0; i < 4; i++)
    {
        if (faller[i].Y >= HEIGHT-1 || BLOCK == map[faller[i].Y + 1][faller[i].X]) {
            return 0;
        }
    }
    memcpy(next_faller, faller, sizeof(faller));
    for ( i = 0; i < 4; i++)
    {
        map[faller[i].Y][faller[i].X] = AIR;
        
    }
    for ( i = 0; i < 4; i++)
    {
        next_faller[i].Y++;
        map[next_faller[i].Y][next_faller[i].X] = MOVING;
    }
    memcpy(faller, next_faller, sizeof(faller));
    return 1;
}
int filled_rows[5];  // 用于记录填满的行索引
int score=0;
u8 clear_row(){
    //从底部往上, 检查是否填满，若填满，则消除一行，并将上面的行下移
    int row, col;
    int filled_count = 0;   // 填满的行数
    int i,r,row_to_clear;

    // 从底部向上检查每一行是否填满
    for (row = HEIGHT - 1; row > 0; row--) {
        int is_full = 1;  // 假设当前行是填满的
        // 检查当前行是否填满
        for (col = 0; col < WIDTH; col++) {
            if (map[row][col] == AIR) {
                is_full = 0;  // 如果发现空位，则当前行未填满
                break;
            }
        }
        // 如果当前行填满，记录行索引
        if (is_full) {
            filled_rows[filled_count++] = row;
        }
    }
    // 如果有填满的行，进行清除和下移操作
    if (filled_count > 0) {
        // return filled_count;

		// // 从最后一行填满的行开始，逐行清除并下移
        // for (i = filled_count - 1; i >= 0; i--) {
        //     row_to_clear = filled_rows[i];

        //     // 将该行上方的所有行下移一行
        //     for (r = row_to_clear; r > 0; r--) {
        //         for (col = 0; col < WIDTH; col++) {
        //             map[r][col] = map[r - 1][col];
        //         }
        //     }
        //     // 清空最顶部的行
        //     for (col = 0; col < WIDTH; col++) {
        //         map[0][col] = AIR;
        //     }
        // }
		for(i=filled_count-1;i>=0;i--){
				row_to_clear = filled_rows[i];
				memcpy(map[row_to_clear],map[row_to_clear-1],WIDTH);
				memset(map[row_to_clear-1],AIR,WIDTH);
		}
		score += filled_count;
    }
    return false;
}

bool is_legal(DIRECTION d) {
    u8 i;
	if (LEFT == d) {
		for ( i = 0; i < 4; i++)
		{
			if (faller[i].X <= 0 || BLOCK == map[faller[i].Y][faller[i].X - 1]) {
				return false;
			}
		}
	}
	else {
		for ( i = 0; i < 4; i++)
		{
			if (faller[i].X >= WIDTH-1 || BLOCK == map[faller[i].Y][faller[i].X + 1]) {
				return false;
			}
		}
	}
	return true;
}


void try_move(DIRECTION d) {
	u8 i;
	if (is_legal(d)) {

		memcpy(next_faller, faller, sizeof(faller));
		for ( i = 0; i < 4; i++)
		{
			map[faller[i].Y][faller[i].X] = AIR;

		}
		for ( i = 0; i < 4; i++)
		{
			next_faller[i].X += (LEFT == d) ? -1 : 1;
			map[next_faller[i].Y][next_faller[i].X] = MOVING;
		}
		memcpy(faller, next_faller, sizeof(faller));
	}

}


bool try_rotate() {
    u8 i;
	switch (now_shape) {
	case O_SHAPE:
		break;
	default:
		for (i = 1; i < 4; i++) {
			next_faller[i].X = faller[0].X + faller[i].Y - faller[0].Y;
			next_faller[i].Y = faller[0].Y - (faller[i].X - faller[0].X);
		}
		for (i = 0; i < 4; i++)
		{
			map[faller[i].Y][faller[i].X] = AIR;

		}
		memcpy(faller, next_faller, sizeof(faller));
		for (i = 0; i < 4; i++)
		{
			map[faller[i].Y][faller[i].X] = MOVING;
		}
		break;
	}
	return true;
}